# -*- coding:utf-8 -*-
import urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, json
from bs4 import BeautifulSoup
import base64
from Crypto.Cipher import AES
import requests


def wxtoken():  # 返回有效的access_token
    f = open('access_token.txt', 'r')
    access_token = f.read()
    f.close()
    return access_token.strip()


def get_access_token():  # 被动获取 通过函数直接获取
    appid = 'wx58c5278a0d5d14cc'
    secret = 'b11dc12700227e639615acdc6f2dae62'
    url = 'https://api.weixin.qq.com/cgi-bin/token'
    text_mod = {'appid': appid, 'secret': secret, 'grant_type': 'client_credential'}
    text_mod = urllib.parse.urlencode(text_mod)
    try:
        req = urllib.request.Request(url='%s%s%s' % (url, '?', text_mod))
        res = urllib.request.urlopen(req).read()
        access_token_req = json.loads(res)
        return access_token_req['access_token']
    except KeyError:
        return access_token_req


def get_user_detail_info(access_token, openid, lang="zh_CN"):  # 获得微信用户详细信息
    url = "https://api.weixin.qq.com/cgi-bin/user/info"
    params = {"access_token": access_token, "openid": openid, "lang": lang}
    req = requests.get(url, params)
    req.encoding = "utf-8"
    return json.loads(req.content)


def qrcode(openid):  # 获得邀请二维码
    req_url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s' % (wxtoken())
    post_data = '{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "%s"}}}' % openid
    req = urllib.request.Request(url=req_url, data=post_data)
    web_data = urllib.request.urlopen(req).read()
    json_data = json.loads(web_data)
    return json_data['url']


# 接收临时登录凭证js_code，获得微信公众号/小程序登录验证session_key和unionid以及小程序的openid等；可以通过返回unioid来识别用户
# 获得的session_key具有时效性，可以在小程序端wx.checkSession来进行检验登录的有效性（session_key有效）
# 每个用户的session_key都是不同的，通过session_key才能获得用户的unionid等信息
def jscode2session(js_code, grant_type='authorization_code'):
    url = 'https://api.weixin.qq.com/sns/jscode2session'
    appid = 'wx1acd991747e3b546'
    secret = '920b4ab8d1bea040af6da7353b3a930b'
    textmod = {"appid": appid, "secret": secret, "js_code": js_code, "grant_type": grant_type}
    textmod = urllib.parse.urlencode(textmod)
    req = urllib.request.Request(url='%s%s%s' % (url, '?', textmod))
    res = urllib.request.urlopen(req).read()
    return res


def authorize(redirect_uri, state=None):  # 返回获得网页认证的链接
    url = 'https://open.weixin.qq.com/connect/oauth2/authorize'
    wechatstring = "#wechat_redirect"
    appid = "gh_2a53362d9d19"
    if state:
        textmod = {"appid": appid, "redirect_uri": redirect_uri, "response_type": "code", "scope": "snsapi_base",
                   "state": state}
    else:
        textmod = {"appid": appid, "redirect_uri": redirect_uri, "response_type": "code", "scope": "snsapi_base"}
    textmod = urllib.parse.urlencode(textmod)
    url = '%s%s%s%s' % (url, '?', textmod, wechatstring)
    return url


def get_all_private_template():  #
    url = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=%s' % (wxtoken())
    req = urllib.request.Request(url=url)
    res = urllib.request.urlopen(req).read()
    return res


def cli(text):  # 返回草料二维码
    url = 'https://cli.im/api/qrcode/code'
    textmod = {'text': text, 'mhid': 'sELPDFnok80gPHovKdI'}
    textmod = urllib.parse.urlencode(textmod)
    req = urllib.request.Request(url='%s%s%s' % (url, '?', textmod))
    res = urllib.request.urlopen(req).read()  # 草料网页源码,以下为采集
    soup = BeautifulSoup(res, 'html.parser')  # html.parser为内置html解释器
    qrcodeurl = 'http:' + soup.img.attrs['src']
    return qrcodeurl


# 通过openid获得草料二维码的图片地址
def getqrcode(openid):
    return cli(qrcode(openid))


def orderSuccess(toUser, order, level_coefficient):  # 通过客服消息成功发送订单信息
    item_title = order['item_title']
    trade_id = str(order['trade_id'])
    alipay_total_price = str(round(float(order['alipay_total_price']), 2))
    pub_share_pre_fee = str(round(float(order['pub_share_pre_fee']) * level_coefficient, 2))
    content = '———下单成功———\n'
    content = content + item_title + '\n'
    content = content + '订单编号：\n'
    content = content + trade_id + '\n'
    content = content + '[红包]实付：' + alipay_total_price + '\n'
    content = content + '[红包]红包：' + pub_share_pre_fee + '\n'
    content = content + '——————————\n'
    content = content + '下单成功，请确认收货第二天后找我拿红包拿来，如果小主觉得我好用，请推荐给朋友哦！'
    return customTextSend(toUser, content)


def orderInfo(toUser, order, level_coefficient):  # 通过客服消息发送订单信息
    item_title = order['item_title']
    trade_id = str(order['trade_id'])
    alipay_total_price = str(round(float(order['alipay_total_price']), 2))
    pub_share_pre_fee = str(round(float(order['pub_share_pre_fee']) * level_coefficient, 2))
    content = '———订单查询———\n'
    content = content + item_title + '\n'
    content = content + '订单编号：\n'
    content = content + trade_id + '\n'
    content = content + '[红包]实付：' + alipay_total_price + '\n'
    content = content + '[红包]红包：' + pub_share_pre_fee + '\n'
    content = content + '——————————\n'
    content = content + '订单查询成功，如果小主觉得我好用，请推荐给朋友哦！'
    return customTextSend(toUser, content)


def customTextSend(toUser, text):  # 发送客服消息,注意条件限制，否则会发送失败
    accesstoken = wxtoken()
    url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s' % (accesstoken)
    postdata = {
        "touser": toUser,
        "msgtype": "text",
        "text": {
            "content": text
        }
    }
    postdata = json.dumps(postdata, ensure_ascii=False).encode('utf-8')
    req = urllib.request.Request(url=url, data=postdata)
    try:
        webdata = urllib.request.urlopen(req).read()
        jsondata = json.loads(webdata)
        return jsondata
    except:
        return None


def templateMsgSend(toUser, first, nick, bindingtime, text, remark):  # 发送模板消息
    url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s' % (wxtoken())
    postdata = {
        "touser": toUser,
        "template_id": "gx-WFRNpRw7RR9HBV-lSpPP13h5gdRwPXc-AK5lffac",
        "data": {
            "first": {
                "value": first,
                "color": "#173177"
            },
            "keyword1": {
                "value": nick,
                "color": "#173177"
            },
            "keyword2": {
                "value": bindingtime,
                "color": "#173177"
            },
            "keyword3": {
                "value": text,
                "color": "#173177"
            },
            "remark": {
                "value": remark,
                "color": "#173177"
            }
        }
    }
    postdata = json.dumps(postdata)
    req = urllib.request.Request(url=url, data=postdata)
    webdata = urllib.request.urlopen(req).read()
    jsondata = json.loads(webdata)
    return jsondata


# 通过seesionKey解密用户的敏感数据，包括nickname,city,unionId等等，平时一般用不到；
# unionId可以通过code2session获得，其他信息也可以通过其他方式获得；
# 这个主要是用于校验用户的信息。
class WXBizDataCrypt:
    def __init__(self, appId, sessionKey):
        self.appId = appId
        self.sessionKey = sessionKey

    def decrypt(self, encryptedData, iv):
        # base64 decode
        sessionKey = base64.b64decode(self.sessionKey)
        encryptedData = base64.b64decode(encryptedData)
        iv = base64.b64decode(iv)
        cipher = AES.new(sessionKey, AES.MODE_CBC, iv)
        decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData)))
        if decrypted['watermark']['appid'] != self.appId:
            raise Exception('Invalid Buffer')
        return decrypted

    def _unpad(self, s):
        return s[:-ord(s[len(s) - 1:])]
